﻿using ContactSMS.Commons.QueryParameters;
using ContactSMS.Commons.Util;
using ContactSMS.Domain;
using ContactSMS.Domain.Entity;
using ContactSMS.Infrastructure.dbContexts;
using ContactSMS.Domain.PagedResult;
using Microsoft.EntityFrameworkCore;
using ContactSMS.Infrastructure.Configs;

namespace ContactSMS.Infrastructure
{
    public class ContactRepository : IContactRepository
    {
        private readonly ContactDbContexts _contactDbContexts;

        public ContactRepository(ContactDbContexts contactDbContexts)
        {
            this._contactDbContexts = contactDbContexts;
        }

        public async Task<Contact?> AddContactAsync(Contact contact)
        {
            await _contactDbContexts.Contacts.AddAsync(contact);
            await _contactDbContexts.SaveChangesAsync();
            return contact;
        }

        public async Task<Contact?> DeleteContactByIdAsync(long id, long userId = 0)
        {
            var existing = await _contactDbContexts.Contacts.FirstOrDefaultAsync(x => x.Id == id && x.UserId == userId);
            if (existing == null)
            {
                return null;
            }
            _contactDbContexts.Contacts.Remove(existing);
            await _contactDbContexts.SaveChangesAsync();
            return existing;
        }

        public async Task<List<Contact>?> DeleteContactByIdsAsync(long[] ids, long userId = 0)
        {
            var contactsToDelete = await _contactDbContexts.Contacts
                                    .Where(contact => ids.Contains(contact.Id) && contact.UserId == userId)
                                    .ToListAsync();
            _contactDbContexts.Contacts.RemoveRange(contactsToDelete);
            await _contactDbContexts.SaveChangesAsync();
            return contactsToDelete;
        }

        public async Task<Contact> GetContactByIdAsync(long id, long userId = 0)
        {
            var result = await _contactDbContexts.Contacts
                .Where(o => o.Id == id)
                .Where(o => o.UserId == userId)
                .Include(o => o.Phones)
                .FirstOrDefaultAsync();
            return result;
        }

        public async Task<PagedContactsResult> GetContactsAsync(ContactQueryParameters parameters, int page = 1, int pageSize = 10, long userId = 0)
        {
            //ContactConfig去掉builder.Ignore(c => c.Phones);
            //Contact实体类 public virtual List<Phone>? Phones { get; set; }
            //就可以使用Include查询且不会映射到数据表中
            var query = _contactDbContexts.Contacts.AsQueryable();
            if (userId > 0)
            {
                query = query.Where(c => c.UserId.Equals(userId));
            }
            // 筛选条件
            if (!string.IsNullOrEmpty(parameters.SearchTerm))
            {
                query = query.Where(c => c.Name.Contains(parameters.SearchTerm) || c.Company.Contains(parameters.SearchTerm) || c.Position.Contains(parameters.SearchTerm) || c.Note.Contains(parameters.SearchTerm));
            }
            if (!string.IsNullOrEmpty(parameters.Name))
            {
                query = query.Where(c => c.Name.Equals(parameters.Name));
            }
            // 排序方式
            if (!string.IsNullOrEmpty(parameters.SortBy))
            {
                query = ApplySorting(query, parameters.SortBy, parameters.SortDescending);
            }
            // 获取总记录数
            var totalCount = await query.CountAsync();
            // 计算总页数
            var totalPages = (int)Math.Ceiling((double)totalCount / pageSize);

            // 分页查询
            var result = await query
                .Include(p => p.Phones)
                .Skip((page - 1) * pageSize)
                .Take(pageSize)
                .ToListAsync();
            return new PagedContactsResult
            {
                Contacts = result,
                CurrentPage = page,
                TotalPages = totalPages,
            };
            /*var query2 = from b in _contactDbContexts.Contacts
                         from p in _contactDbContexts.Phones.Where(p => b.Id == p.ContactId).DefaultIfEmpty()
                         select new { b, p };

            // 筛选条件
            if (!string.IsNullOrEmpty(parameters.SearchTerm))
            {
                query2 = query2.Where(x => x.b.Name.Contains(parameters.SearchTerm) ||
                                           x.b.Company.Contains(parameters.SearchTerm) ||
                                           x.b.Position.Contains(parameters.SearchTerm) ||
                                           x.b.Note.Contains(parameters.SearchTerm) ||
                                           x.p.Mobile.Contains(parameters.SearchTerm));
            }
            if (!string.IsNullOrEmpty(parameters.Name))
            {
                query2 = query2.Where(x => x.b.Name == parameters.Name);
            }
            if (!string.IsNullOrEmpty(parameters.Mobile))
            {
                query2 = query2.Where(x => x.p.Mobile == parameters.Mobile);
            }
            // 排序
            if (!string.IsNullOrEmpty(parameters.SortBy))
            {
                switch (parameters.SortBy.ToLower())
                {
                    case "name":
                        query2 = parameters.SortDescending ? query2.OrderByDescending(x => x.b.Name) : query2.OrderBy(x => x.b.Name);
                        break;
                    // 添加其他排序条件
                    default:
                        break;
                }
            }
            // 计算总记录数
            var totalCount = await query2.Distinct().CountAsync();
            // 计算总页数
            var totalPages = (int)Math.Ceiling((double)totalCount / pageSize);
            // 分页查询
            var contacts = await query2
                .Distinct()
                .Skip((page - 1) * pageSize)
                .Take(pageSize)
                .ToListAsync();
            // 从结果中提取联系人信息
            var contactList = contacts.Select(c => c.b).ToList();
            var phoneList = contacts.Select(c => c.p).ToList();
            List<Contact> list = new List<Contact>();
            HashSet<long> contactIds = new HashSet<long>();
            foreach (var item in contactList)
            {
                if (!contactIds.Contains(item.Id))
                {
                    list.Add(item);
                    contactIds.Add(item.Id);
                }
            }
            foreach (var phone in phoneList)
            {
                if (phone != null)
                {
                    for (int i = 0; i < list.Count; i++)
                    {
                        if (list[i].Id == phone.ContactId)
                        {
                            if (list[i].Phones == null)
                            {
                                list[i].Phones = new List<Phone>();
                            }
                            list[i].Phones.Add(phone);
                            break; // 找到匹配的联系人后立即退出循环
                        }
                    }
                }
            }
            return new PagedContactsResult
            {
                Contacts = list,
                CurrentPage = page,
                TotalPages = totalPages,
            };*/

            /*// 构建查询
            var query = _contactDbContexts.Contacts.AsQueryable();
            // 筛选条件
            if (!string.IsNullOrEmpty(parameters.SearchTerm))
            {
                query = query.Where(c => c.Name.Contains(parameters.SearchTerm) || c.Company.Contains(parameters.SearchTerm) || c.Position.Contains(parameters.SearchTerm) || c.Note.Contains(parameters.SearchTerm));
            }
            if (!string.IsNullOrEmpty(parameters.Name))
            {
                query = query.Where(c => c.Name.Equals(parameters.Name));
            }
            // 排序方式
            if (!string.IsNullOrEmpty(parameters.SortBy))
            {
                query = ApplySorting(query, parameters.SortBy, parameters.SortDescending);
            }
            // 获取总记录数
            var totalCount = await query.CountAsync();
            // 计算总页数
            var totalPages = (int)Math.Ceiling((double)totalCount / pageSize);

            // 分页查询
            var result = await query
                //.Include()
                .Skip((page - 1) * pageSize)
                .Take(pageSize)
                .ToListAsync();
            if (result.Count > 0)
            {
                foreach (var item in result)
                {
                    var phone = await _contactDbContexts.Phones.Where(x => x.ContactId == item.Id).ToListAsync();
                    if (phone != null)
                    {
                        item.Phones = phone;
                    }
                }
            }
            return new PagedContactsResult
            {
                Contacts = result,
                CurrentPage = page,
                TotalPages = totalPages,
            };*/
        }

        public async Task<Contact?> UpdateContactAsync(long id, Contact contact)
        {
            var existing = await _contactDbContexts.Contacts.FirstOrDefaultAsync(x => x.Id == id);
            if (existing == null)
            {
                return null;
            }
            existing.Name = contact.Name;
            existing.Company = contact.Company;
            existing.Position = contact.Position;
            existing.UpdateTime = TimeUtil.GetTimestamp();
            await _contactDbContexts.SaveChangesAsync();
            return existing;
        }

        private IQueryable<Contact> ApplySorting(IQueryable<Contact> query, string sortBy, bool sortDescending)
        {
            // 根据排序字段和排序方向对查询进行排序
            switch (sortBy.ToLower())
            {
                case "name":
                    query = sortDescending ? query.OrderByDescending(c => c.Name) : query.OrderBy(c => c.Name);
                    break;
                case "initial":
                    query = sortDescending ? query.OrderByDescending(c => c.Initial) : query.OrderBy(c => c.Name);
                    break;
                case "pinyin":
                    query = sortDescending ? query.OrderByDescending(c => c.PinYin) : query.OrderBy(c => c.Name);
                    break;
                // 可以根据需要添加更多的排序字段
                default:
                    // 默认按照 ID 排序
                    query = sortDescending ? query.OrderByDescending(c => c.Id) : query.OrderBy(c => c.Id);
                    break;
            }

            return query;
        }
    }
}
